/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package former;

import Tables.AbstractTable;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;


public abstract class AbstractFormer 
{
    private String sql="";
    private String tableName;
    private String tableCol;
    private List columnsList;
    private List dataList;
    private enum Mode
    {
        custom,full;
    }

    public AbstractFormer() {
        
    }
    protected abstract String formQueryHelper(AbstractTable object);
    /**
     *
     * @param object
     * @return
     */
    public abstract String formQuery(AbstractTable object) throws Exception; 
    protected boolean initializeQuery(AbstractTable object)
    {
        boolean noError = initializeTableColAndData(object);
        noError&=initializeTableName(object);
        return noError;
    }
    
    private boolean initializeTableName(AbstractTable object)
    {
        tableName = object.getClass().getSimpleName();
        return true;
    }
    private boolean initializeTableColAndData(AbstractTable object)
    {
        boolean noError=true;
        StringBuilder builder=new  StringBuilder();
        columnsList = new ArrayList();
        if(object.isCustom&&object.customizedColumns!=null)
        {
           noError= initializeTableData(object,Mode.custom);
           boolean end=false;
           if(noError)
           {
              while(noError&&!end)
              {
                  for(int i=0;i<object.customizedColumns.length;i++)
                  {
                      if(i!=0)
                      {
                          builder.append(" , ");
                      }
                      builder.append(object.customizedColumns[i]);
                      columnsList.add(object.customizedColumns[i]);
                  }
                  end=true;
              }  
           }
        }
        else
        {
          noError= initializeTableData(object,Mode.full);
          if(noError)
          {
              try {
                    int i=0;
                    for (PropertyDescriptor pd : Introspector.getBeanInfo(object.getClass()).getPropertyDescriptors()) 
                    {
                        
                         if (pd.getReadMethod() != null && !"class".equals(pd.getName()))
                         {
                            if(i!=0)
                            {
                              builder.append(" , ") ;
                            }
                            try
                            {
                                builder.append(pd.getName());
                                columnsList.add(pd.getName());
                            }
                            catch(Exception ex)
                            {
                                noError=false;
                                break;
                            }
                            i++;
                         }            
                    }
                } 
            catch (IntrospectionException ex) 
            {
                noError=false;
                Logger.getLogger(AbstractFormer.class.getName()).log(Level.SEVERE, null, ex);
            }
          }
        }
        if(noError)
       {
           tableCol = builder.toString();
       }
        return noError;
    }
    private boolean initializeTableData(AbstractTable object , Mode mode)
    {
        dataList=new ArrayList();
        boolean noError=true;
        StringBuilder builder = new  StringBuilder();
        if(mode==Mode.custom)
        {
            for(int i=0;i<object.customizedColumns.length;i++)
            {        
               try
                {
                    Object obj=getFieldValue(object.customizedColumns[i], object);
                    dataList.add("'"+obj+"'");
                }
                catch(Exception ex)
                {
                    noError=false;
                    break;
                }
            }
        }
        else
        {
            try {
 
                    int i=0;
                    
                    for (PropertyDescriptor pd : Introspector.getBeanInfo(object.getClass()).getPropertyDescriptors()) 
                    {
                         if (pd.getReadMethod() != null && !"class".equals(pd.getName()))
                         {
                            
                            try
                            {
                                dataList.add("'"+getFieldValue(pd.getName(), object)+"'");
                            }
                            catch(Exception ex)
                            {
                                noError=false;
                                break;
                            }
                         }  
                         i++;
                         
                    }
                } 
            catch (IntrospectionException ex) 
            {
                noError=false;
                Logger.getLogger(AbstractFormer.class.getName()).log(Level.SEVERE, null, ex);
            }
     }
       if(!noError)
       {
           dataList.clear();
       }
      return noError;
    }
    
    private static Object getFieldValue(String fieldName,AbstractTable obj) {
        Object value=null;
        try 
        {
            PropertyDescriptor propertyDescriptor = new PropertyDescriptor(fieldName, obj.getClass());
            value=propertyDescriptor.getReadMethod().invoke(obj); 
        } 
        catch (IllegalAccessException ex) 
        {
            ex.printStackTrace();
            System.out.println(ex.getMessage());
        }
        catch (IllegalArgumentException ex) 
        {
            ex.printStackTrace();
            System.out.println(ex.getMessage());
        } 
        catch (InvocationTargetException ex) 
        {
            ex.printStackTrace();
            System.out.println(ex.getMessage());            
        }
        catch (IntrospectionException ex)
        {
            ex.printStackTrace();
            System.out.println(ex.getMessage());            
        }
        return value;
    }
    public List getDataList()
    {
        return dataList;
    }

    public String getSql() {
        return sql;
    }

    public void setSql(String sql) {
        this.sql = sql;
    }

    protected String getTableName() {
        return tableName;
    }

    protected String getTableCol() {
        return tableCol;
    }

    public List getColumnsList() {
        return columnsList;
    }
    
    
}
